﻿using System.Collections.Generic;
using System.Linq;
using DataAccessLayer;

namespace Editor
{
    /// <summary>
    /// Manages the model and the view.
    /// </summary>
    public sealed class EditorPresenter : IEditorPresenter
    {
        private GameData Model;
        private readonly IBusinessLogicLayer Bll;

        public EditorPresenter()
        {
            Bll = BusinessLogicLayer.UniqueInstance;
        }

        public EditorStartData LoadApplicationData(string filename)
        {
            EditorStartData startData = Bll.LoadApplicationData(filename);
            Model = startData.GameData;
            return startData;
        }

        public string[] GetFiles()
        {
            return Bll.GetFiles("");
        }

        public GameObject GetGameObject(int objId)
        {
            return Model.Protagonists.Single(obj => obj.ID == objId);
        }

        public void RemoveGameObject(int objId)
        {
            //GameObject obj = Model.Protagonists.Single(gobj => gobj.ID == objId);
            //Model.Protagonists.Remove(obj);
        }

        public EditorRect GetCollisionRect(int objId, int rectIndex)
        {
            //GameObject obj = GetGameObject(objId);
            //return obj.CollisionRects[rectIndex];

            return default(EditorRect);
        }

        public void SetCollisionRectangle(int objId, int rectIndex, EditorRect rect)
        {
            //GameObject obj = GetGameObject(objId);
            //int index = Model.GameObjects.IndexOf(obj);
            //Model.GameObjects[index].CollisionRects[rectIndex] = rect;
        }

        public void AddCollisionRectangle(int id, EditorRect rect)
        {
            //GameObject obj = GetGameObject(id);
            //int index = Model.GameObjects.IndexOf(obj);
            //Model.GameObjects[index].CollisionRects.Add(rect);
        }

        public EditorRect GetSourceRect(int objId)
        {
            GameObject obj = GetGameObject(objId);
            return obj.SourceRect;
        }

        public void SetSourceRectangle(int objId, EditorRect rect)
        {
            //GameObject obj = GetGameObject(objId);
            //int index = Model.Protagonists.IndexOf(obj);
            //Model.Protagonists[index].SourceRect = rect;
        }

        public EditorVector2 GetPosition(int objId)
        {
            GameObject obj = GetGameObject(objId);
            return obj.Position;
        }

        public void SetPosition(int objId, EditorVector2 position)
        {
            //GameObject obj = GetGameObject(objId);
            //int index = Model.Protagonists.IndexOf(obj);
            //Model.Protagonists[index].Position = position;
        }

        public EditorVector2 GetDirection(int objId)
        {
            //GameObject obj = GetGameObject(objId);
            //return obj.Direction;

            return default(EditorVector2);
        }

        public void SetDirection(int objId, EditorVector2 dir)
        {
            //GameObject obj = GetGameObject(objId);
            //int index = Model.GameObjects.IndexOf(obj);
            //Model.GameObjects[index].Direction = dir;
        }

        public ObjectStats GetStats(int id)
        {
            //GameObject obj = GetGameObject(id);
            //int index = Model.GameObjects.IndexOf(obj);
            //return Model.GameObjects[index].Stats;

            return null;
        }

        public void SetStats(int id, ObjectStats stats)
        {
            //GameObject obj = GetGameObject(id);
            //int index = Model.GameObjects.IndexOf(obj);
            //Model.GameObjects[index].Stats = stats;
        }

        public GameMenu GetMenu(int index)
        {
            return Model.Menus[index];
        }

        public void AddMenu(GameMenu menu)
        {
            Model.Menus.Add(menu);
        }

        public List<MenuOption> GetMenuOptions(int menuIndex)
        {
            return Model.Menus[menuIndex].MenuOptions;
        }

        public void SetTextureName(int id, string name)
        {
            //GameObject obj = GetGameObject(id);
            //int index = Model.Protagonists.IndexOf(obj);
            //Model.Protagonists[index].TextureName = name;
        }

        public void SaveGameFile(string curFilename)
        {
            Bll.SaveGameFile(Model, curFilename);
        }

        public int GetObjectCount()
        {
            return Model.Protagonists.Count;
        }

        public T AddGameObject<T>() where T: GameObject, new()
        {
            int id = Model.Protagonists.Count + 1;

            T obj = new T
                        {
                            ID = Model.Protagonists.Any(gObj => gObj.ID == id)
                                     ? Model.Protagonists.Max(maxObjID => maxObjID.ID) + 1
                                     : id
                        };

            //Model.Protagonists.Add(obj);

            return obj;
        }

        public void AddGameObject<T>(ref T obj) where T : GameObject
        {
            int id = Model.Protagonists.Count + 1;

            obj.ID = Model.Protagonists.Any(gObj => gObj.ID == id)
                         ? Model.Protagonists.Max(maxObjID => maxObjID.ID) + 1
                         : id;

           // Model.Protagonists.Add(obj);
        }

        public IList<T> GetObjects<T>() where T : GameObject
        {
            return Model.Protagonists.Where(obj => obj is T).Cast<T>().ToList();
        }

        public GameLevel GetLevel(int index, int id = -1)
        {
            if (index < 0 && id > 0)
                return Model.Levels.Single(lvl => lvl.ID == id);

            return Model.Levels[index];
        }

        public int GetLevelCount()
        {
            return Model.Levels.Count;
        }

        public void AddLevel(GameLevel gameLevel)
        {
            Model.Levels.Add(gameLevel);
        }

        public void SetLevel(int index, GameLevel level)
        {
            Model.Levels[index] = level;
        }

        public void RemoveLevel(int index)
        {
            Model.Levels.RemoveAt(index);
        }

        public void RemoveCollisionRectangle(int id, int index)
        {
            //int objIndex = Model.GameObjects.IndexOf(Model.GameObjects.Single(go => go.ID == id));
            //Model.GameObjects[objIndex].CollisionRects.RemoveAt(index);
        }
    }
}